<template>
  <el-dialog :model-value="dialogVisible" :title="dialogTitle" @close="cancelForm" @open="getFileOption">
    <el-form label-width="130px" ref="formRef3" :rules="createTaskRules" :model="form">
      <el-form-item label="任务标题" prop="taskName">
        <el-input placeholder="请输入任务标题" v-model="form.taskName"></el-input>
      </el-form-item>

      <el-form-item label="任务优先级" prop="level">
        <el-select placeholder="请选择任务优先级" v-model="form.level">
          <el-option value="0" label="低"/>
          <el-option value="1" label="高"/>
          <el-option value="2" label="极高"/>
        </el-select>
      </el-form-item>

      <el-form-item label="指派任务成员" prop="userIds">
        <el-select v-model="form.userIds" placeholder="请选择任务成员" multiple filterable>
          <el-option v-for="item in userOptions"
                     :key="item.id"
                     :label="item.username"
                     :value="item.id"/>
        </el-select>
      </el-form-item>

      <el-form-item label="指派任务负责人" prop="handlerId">
        <el-select v-model="form.handlerId" placeholder="请选择负责人" filterable>
          <el-option v-for="item in userOptions"
                     :key="item.id"
                     :label="item.username"
                     :value="item.id"/>
        </el-select>
      </el-form-item>
      <el-form-item label="项目进度">
        <div ref="progressBox" class="progress" @mousedown="onDragStart">
          <div class="slider-demo-block">
            <el-slider v-model="form.process" :marks="marks"/>
          </div>
        </div>
      </el-form-item>

      <!-- 附件上传 -->
      <el-form-item label="附件上传" ref="uploadElement">
        <el-upload
            v-model:file-list="fileList"
            class="upload-demo"
            action=""
            :limit="5"
            accept=".pdf,.md,.doc,.docx,.png,.jpg,.jpeg"
            multiple
            :auto-upload="false"
            :on-preview="handlePreview"
            :on-remove="handleRemove"
            :before-remove="beforeRemove"
            :on-exceed="handleExceed"
            :before-upload="beforeUpload"
            :on-change="handleFileChange"
        >
          <el-button type="primary">添加附件</el-button>
          <template #tip>
            <div class="el-upload__tip">
              双击文件列表下载
            </div>
          </template>
        </el-upload>
      </el-form-item>

      <el-form-item label="是否立即发布">
        <el-switch v-model="form.isPublish"/>
      </el-form-item>

      <el-form-item label="任务时间" v-if="form.isPublish">
        <el-date-picker
            v-model="form.time"
            type="datetimerange"
            range-separator="到"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            format="YYYY-MM-DD HH:mm:ss"
        value-format="YYYY-MM-DD HH:mm:ss"
        />
      </el-form-item>

      <el-form-item>
        <div class="button-container">
          <el-button type="primary" @click="submitForm" :loading="fullscreenLoading">确认</el-button>
          <el-button @click="cancelForm">取消</el-button>
        </div>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<script setup>
import {onMounted, onUnmounted, reactive, ref, toRefs, watch} from "vue";
import {defineProps, defineEmits} from "vue";
import {save, update, getUser, getFileList, deleteFile, downloadFile, uploadFile} from "@/api/task/task.js"
import {useRoute, useRouter} from "vue-router";
import {ElMessage, ElMessageBox} from "element-plus";

const router = useRouter()
const route = useRoute()
const isDragEnd = ref(false)
const deleteFileList = ref([])


const form = ref({
  time: [],
  isPublish: 1,
  userIds: [],
  handlerId: "",
  process: 0,
  taskName: "",
  level: "0"
})

const userOptions = ref([])
const formRef3 = ref(null)


const createTaskRules = {
  level: [{required: true, message: "请选择任务优先级", trigger: "blur"}],
  userIds: [{required: true, message: "请选择任务成员", trigger: "blur"}, {
    validator: (rule, value, callback) => {
      // 假设 handlerId 存放在 this.form.handlerId 中
      const handlerId = form.value.handlerId;
      if (!value || !handlerId || value.indexOf(handlerId) === -1) {
        callback(new Error("任务成员必须包含负责人"));
      } else {
        callback();
      }
    },
    trigger: "blur"
  }],
  handlerId: [{required: true, message: "请选择负责人", trigger: "blur"}],
  taskName: [{required: true, message: "请输入任务标题", trigger: "blur"}],
};
const beforeUpload = (file) => {
  const isValidType = [
    'application/pdf',
    'text/markdown',
    'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'image/png',
    'image/jpeg'
  ].includes(file.type);
  const isLt2M = file.size / 1024 / 1024 < 2;

  if (!isValidType) {
    ElMessage.error('上传文件格式不正确');
  }
  if (!isLt2M) {
    ElMessage.error('上传文件大小不能超过 2MB');
  }
  return isValidType && isLt2M;
}
// 定义接收的 props（这里定义了 dialogVisible 和 dialogTitle）
const props = defineProps({
  dialogVisible: {
    type: Boolean,
    default: false,
  },
  dialogTitle: {
    type: String,
    default: "新增任务",
  },
  getList: {
    type: Function
  },
  formData: {
    type: Object
  }
});
const timeTurn = (originalDateStr) => {
  console.log(333, originalDateStr)
  if (!originalDateStr) {
    console.error("Invalid date string:", originalDateStr);
    return;
  }

  // 将原始日期字符串转换为 Date 对象（已包含秒的处理）
  const date = new Date(originalDateStr.replace(
      /(\d{4})\/(\d{2})\/(\d{2}) (\d{2}):(\d{2}):(\d{2})/,
      '$1-$2-$3T$4:$5:$6'
  ));

  // 获取年份、月份、日期、小时、分钟和秒
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hours = String(date.getHours()).padStart(2, '0');
  const minutes = String(date.getMinutes()).padStart(2, '0');
  const seconds = String(date.getSeconds()).padStart(2, '0'); // 新增秒的获取

  // 构建包含秒的时间格式
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; // 添加秒字段
}
watch(() => props.formData, (value) => {
  console.log(11111)
  form.value.time = []
  form.value = {...value}
  form.value.time = [timeTurn(form.value.taskStartTime), timeTurn(form.value.taskEndTime)]

  form.value.isPublish = form.value.isPublish === 1;
}, {deep: true})


const marks = reactive({
  30: '30%',
  50: {
    style: {
      color: '#1989FA',
    },
    label: '50%',
  },
  70: '70%',
})

const progressBox = ref(null);

const onDragStart = (event) => {
  isDragEnd.value = true;
  updateProgress(event); // **保证鼠标点击时立即同步进度**
  document.addEventListener("mouseup", onDragEnd);
  document.addEventListener("mousemove", onDrag);
};

const updateProgress = (event) => {
  if (progressBox.value) {
    const rect = progressBox.value.getBoundingClientRect();
    const width = rect.width;
    const offsetX = event.clientX - rect.left;
    let percentage = Math.round((offsetX / width) * 100);
    form.value.process = Math.max(0, Math.min(percentage, 100));
  }
};

const onDragEnd = () => {
  isDragEnd.value = false;
  document.removeEventListener("mousemove", onDrag);
};
const onDrag = (event) => {
  if (isDragEnd.value && progressBox.value) {
    const rect = progressBox.value.getBoundingClientRect();
    const width = rect.width;
    const offsetX = event.clientX - rect.left;
    let percentage = Math.round((offsetX / width) * 100);
    form.value.process = Math.max(0, Math.min(percentage, 100));
  }
};

// 组件卸载时移除事件监听，避免内存泄漏
onUnmounted(() => {
  document.removeEventListener("mouseup", onDragEnd);
  document.removeEventListener("mousemove", onDrag);

});
onMounted(() => {
  getUserOption()
})


// 定义更新 props 的事件，用于 v-model 的双向绑定
const emit = defineEmits(["changeDialogVisible", "getData"]);
const clickTimeout = ref(null);
const {dialogVisible} = toRefs(props); //直接使用props中的sonData
const fullscreenLoading = ref(false)
const submitForm = async () => {
  formRef3.value.validate(async valid => {
    if (valid) {
      const data = {...form.value}
      data.taskStartTime = form.value.time[0]
      data.taskEndTime = form.value.time[1]
      data.projectId = route.query.id
      if (data.isPublish) {
        data.isPublish = 1
      } else {
        data.isPublish = 0
      }

      const formData = new FormData();
      formData.append('taskRequest', new Blob([JSON.stringify(data)], {type: 'application/json'})); // JSON 数据
      fileList.value.forEach(file => {
        if (!file.isExit) {
          formData.append("files", file.raw); // `file.raw` 才是真正的文件
        }
      });
      fullscreenLoading.value = true
      try {
        if (props.dialogTitle === "新增项目") {
          formData.append('taskId', "");
          const res = await save(formData)
          if (res.data.code === 200) {
            ElMessage.success('新增成功')
            emit('changeDialogVisible', false);
            props.getList()
          } else {
            ElMessage.error('新增失败')
          }
        } else {
          formData.append('taskId', props.formData.id);
          deleteFileList.value.forEach(file => {
            formData.append("fileIds", file.id); // `file.raw` 才是真正的文件
          });
          const res = await update(formData)
          if (res.data.code === 200) {
            emit('changeDialogVisible', false);
            ElMessage.success('编辑成功')
            props.getList()
          } else {
            ElMessage.error('编辑失败')
          }
        }
      } catch (e) {
        fullscreenLoading.value = false
      }
      fullscreenLoading.value = false
    } else {
      console.log("验证未通过")
    }
  })

};

const getUserOption = async () => {
  const res = await getUser(route.query.id)
  userOptions.value = res.data.result
}

const getFileOption = async () => {
  fileList.value = []
  let taskId = ""
  if (!(props.dialogTitle === "新增项目")) {
    taskId = props.formData.id
  }
  const res = await getFileList(taskId)
  res.data.result.forEach(item => {
    item.name = item.fileNameUp
    item.isExit = true
    fileList.value.push(item)
  })
}

const download = async (id) => {
  const res = await downloadFile(id)
  // 获取文件内容
  const blob = await res.blob();

  // 创建一个临时的 a 标签用于下载
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;

  // 设置下载文件名（从响应头中提取）
  const contentDisposition = res.headers.get("Content-Disposition");
  let filename = "exported_file.xlsx"; // 默认文件名
  if (contentDisposition && contentDisposition.includes("filename=")) {
    const match = contentDisposition.match(/filename="?(.+)"?/);
    if (match && match[1]) {
      filename = decodeURIComponent(match[1]);
    }
  }

  a.download = filename; // 设置下载文件名

  // 将 a 标签添加到 DOM 中并触发点击事件
  document.body.appendChild(a);
  a.click();

  // 清理临时对象
  window.URL.revokeObjectURL(url);
  document.body.removeChild(a);

  // Feng.success("成功导出!");

}
const upload = async () => {
  const formData = new FormData();
  fileList.value.forEach(file => {
    if (!file.isExit) {
      formData.append("files", file.raw); // `file.raw` 才是真正的文件
    }

  });
  const res = await uploadFile(formData, route.query.id)
  // userOptions.value = res.data.result
}

const removeFile = async () => {
  const formData = new FormData();
  deleteFileList.value.forEach(file => {
    formData.append("id", file.raw); // `file.raw` 才是真正的文件
  });
  const res = await deleteFileList(formData)
  // userOptions.value = res.data.result
}
const cancelForm = () => {
  emit('changeDialogVisible', false);
};

const fileList = ref([])

const handleFileChange = (file, fileListNew) => {
  fileList.value = fileListNew;  // 更新文件列表
};

const handleRemove = (file, fileListNew) => {
  fileList.value = fileListNew;  // 移除后更新文件列表
};

const handlePreview = (uploadFile) => {
  if (clickTimeout.value) {
    clearTimeout(clickTimeout.value);
    clickTimeout.value = null;
    // downloadFile(file);
    download(uploadFile.id)
    // download()
  } else {
    clickTimeout.value = setTimeout(() => {
      clickTimeout.value = null;
      // 单击事件的逻辑（如果需要）
    }, 1000); // 双击检测的时间间隔
  }
  console.log(uploadFile)
}

const handleExceed = (files, uploadFiles) => {
  ElMessage.warning(
      `The limit is 3, you selected ${files.length} files this time, add up to ${
          files.length + uploadFiles.length
      } totally`
  )
}

const beforeRemove = (file, fileList) => {
  deleteFileList.value = fileList
}

</script>
<style scoped>
.button-container {
  width: 100%;
  margin-left: 0 !important;
  display: flex;
  flex-direction: row-reverse;
  gap: 20px;
}

.progress {
  width: 100%;
}
</style>
